package cn.wch.meshlib.frame.ack;

import androidx.annotation.NonNull;

import java.math.BigInteger;
import java.util.Arrays;

import cn.wch.blelib.utils.FormatUtil;
import cn.wch.blelib.utils.LogUtil;
import cn.wch.meshlib.ota.ChipType;
import cn.wch.meshlib.ota.ImageInfo;

/**
 * 应答帧
 */
public class AckFrame {
    /**应答类型*/
    @AckType byte ackType;
    /**网络地址*/
    int netAddress;
    /**更新地址*/
    int updateAddress;
    /**开始代码*/
    int statusCode;
    /**数据缓存*/
    byte[] data;
    /**图像大小*/
    long imageSize;
    /**块大小*/
    int blockSize;
    /**芯片类型*/
    byte[] chipType;

    int ivIndex;
    byte flag;

    /**
     * 实例化应答格式
     * @param ackType 应答类型。限制在{@link AckType}范围内
     */
    public AckFrame(@AckType byte ackType) {
        this.ackType = ackType;
    }

    /**
     * 获取应答类型,限制在{@link AckType}范围内
     * @return
     */
    public @AckType byte getAckType() {
        return ackType;
    }

    /**
     * 设置应答类型
     * @param ackType 应答类型。限制在{@link AckType}范围内
     */
    public void setAckType(@AckType byte ackType) {
        this.ackType = ackType;
    }
    public int getNetAddress() {
        return netAddress;
    }
    public void setNetAddress(int netAddress) {
        this.netAddress = netAddress;
    }
    public int getUpdateAddress() {
        return updateAddress;
    }
    public void setUpdateAddress(int updateAddress) {
        this.updateAddress = updateAddress;
    }
    public int getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }
    public byte[] getData() {
        return data;
    }
    public void setData(byte[] data) {
        this.data = data;
    }
    public long getImageSize() {
        return imageSize;
    }
    public void setImageSize(long imageSize) {
        this.imageSize = imageSize;
    }
    public int getBlockSize() {
        return blockSize;
    }
    public void setBlockSize(int blockSize) {
        this.blockSize = blockSize;
    }
    /**获取芯片类型信息*/
    public byte[] getChipType() {
        return chipType;
    }
    public void setChipType(byte[] chipType) {
        this.chipType = chipType;
    }

    public int getIvIndex() {
        return ivIndex;
    }

    public void setIvIndex(int ivIndex) {
        this.ivIndex = ivIndex;
    }

    public byte getFlag() {
        return flag;
    }

    public void setFlag(byte flag) {
        this.flag = flag;
    }

    public ImageInfo toImageInfo(){
        if(this.getAckType()!= AckType.IMAGE_INFO){
            return null;
        }
        ImageInfo imageInfo = new ImageInfo();
        byte[] chipType = this.getChipType();
        int b1 = chipType[0] & 0xff;
        int b2 = chipType[1] & 0xff;
        if(b1==0x83 && b2==0x00){
            imageInfo.setChipType(ChipType.CH583);
        }else if(b1==0x73 && b2==0x00) {
            imageInfo.setChipType(ChipType.CH573);
        }else if(b1==0x08 && b2==0x02) {
            imageInfo.setChipType(ChipType.CH32V208);
        }else if(b1==0x08 && b2==0xf2) {
            imageInfo.setChipType(ChipType.CH32F208);
        }else {
            imageInfo.setChipType(ChipType.UNKNOWN);
        }
        imageInfo.setImageSize(imageSize);
        imageInfo.setBlockSize(blockSize);

        return imageInfo;
    }

    @Override
    public String toString() {
        return "AckFrame{" +
                "ackType=" + ackType +
                ", netAddress=" + netAddress +
                ", updateAddress=" + updateAddress +
                ", statusCode=" + statusCode +
                ", data=" + FormatUtil.bytesToHexString(data) +
                ", imageSize=" + imageSize +
                ", blockSize=" + blockSize +
                ", chipType=" + FormatUtil.bytesToHexString(chipType) +
                ", ivIndex=" + ivIndex +
                ", flag=" + flag +
                '}';
    }

    /**
     * 翻转字节数组
     * @param data
     * @return
     */
    private static byte[] flipByteArray(@NonNull byte[] data){
        byte[] target=new byte[data.length];

        for(int i=0;i<data.length;i++){
            target[i]=data[data.length-1-i];
        }
        return target;
    }

    /**
     * 字节数组到小端整型数（低位在前）
     * @param a
     * @param start
     * @param len
     * @return
     */
    public static int bytesToIntLittleEndian(byte[] a, int start,int len) {
        int s = 0;
        for (int i = 0; i < len; i++) {
            int i1 = (a[start + i] & 0x000000ff)<< (8 * i);
            s|=i1;
        }
        return s;
    }
}
